package glpm

import (
	"context"
	"fmt"
	"strings"
)

// GLPM 主包管理器结构体
type GLPM struct {
	factory *ManagerFactory
}

// NewGLPM 创建新的GLPM实例
func NewGLPM() *GLPM {
	return &GLPM{
		factory: NewManagerFactory(),
	}
}

// OnlinePackageManager 在线包管理器包装器
type OnlinePackageManager struct {
	manager PackageManager
}

// NewOnlinePackageManager 创建在线包管理器
func NewOnlinePackageManager(config *ManagerConfig) (*OnlinePackageManager, error) {
	if config == nil {
		config = NewManagerConfig()
	}
	config.ManagerType = OnlineManagerType

	factory := NewManagerFactory()
	mgr, err := factory.CreateManager(config)
	if err != nil {
		return nil, err
	}

	return &OnlinePackageManager{
		manager: mgr,
	}, nil
}

// IsManagerAvailable 检查包管理器是否可用
func (opm *OnlinePackageManager) IsManagerAvailable() bool {
	return opm.manager.IsAvailable()
}

// GetManagerName 获取包管理器名称
func (opm *OnlinePackageManager) GetManagerName() string {
	return opm.manager.Name()
}

// Install 安装包
func (opm *OnlinePackageManager) Install(ctx context.Context, packages []string) error {
	return opm.manager.Install(ctx, packages)
}

// Remove 移除包
func (opm *OnlinePackageManager) Remove(ctx context.Context, packages []string) error {
	return opm.manager.Remove(ctx, packages)
}

// Update 更新包列表
func (opm *OnlinePackageManager) Update(ctx context.Context) error {
	return opm.manager.Update(ctx)
}

// Upgrade 升级包
func (opm *OnlinePackageManager) Upgrade(ctx context.Context, packages []string) error {
	return opm.manager.Upgrade(ctx, packages)
}

// Search 搜索包
func (opm *OnlinePackageManager) Search(ctx context.Context, pattern string) ([]PackageInfo, error) {
	return opm.manager.Search(ctx, pattern)
}

// Info 获取包信息
func (opm *OnlinePackageManager) Info(ctx context.Context, packageName string) (*PackageInfo, error) {
	return opm.manager.Info(ctx, packageName)
}

// ListInstalled 列出已安装的包
func (opm *OnlinePackageManager) ListInstalled(ctx context.Context) ([]PackageInfo, error) {
	return opm.manager.ListInstalled(ctx)
}

// IsInstalled 检查指定包是否已安装
func (opm *OnlinePackageManager) IsInstalled(ctx context.Context, packageName string) (bool, error) {
	return opm.manager.IsInstalled(ctx, packageName)
}

// OfflinePackageManager 离线包管理器包装器
type OfflinePackageManager struct {
	manager PackageManager
}

// NewOfflinePackageManager 创建离线包管理器
func NewOfflinePackageManager(config *ManagerConfig) (*OfflinePackageManager, error) {
	if config == nil {
		config = NewManagerConfig()
	}
	config.ManagerType = OfflineManagerType

	factory := NewManagerFactory()
	mgr, err := factory.CreateManager(config)
	if err != nil {
		return nil, err
	}

	return &OfflinePackageManager{
		manager: mgr,
	}, nil
}

// IsManagerAvailable 检查包管理器是否可用
func (opm *OfflinePackageManager) IsManagerAvailable() bool {
	return opm.manager.IsAvailable()
}

// GetManagerName 获取包管理器名称
func (opm *OfflinePackageManager) GetManagerName() string {
	return opm.manager.Name()
}

// Install 安装包
func (opm *OfflinePackageManager) Install(ctx context.Context, packages []string) error {
	return opm.manager.Install(ctx, packages)
}

// Remove 移除包
func (opm *OfflinePackageManager) Remove(ctx context.Context, packages []string) error {
	return opm.manager.Remove(ctx, packages)
}

// Update 更新包列表（离线包管理器不支持）
func (opm *OfflinePackageManager) Update(ctx context.Context) error {
	return fmt.Errorf("离线包管理器不支持更新操作")
}

// Upgrade 升级包（离线包管理器不支持）
func (opm *OfflinePackageManager) Upgrade(ctx context.Context, packages []string) error {
	return fmt.Errorf("离线包管理器不支持升级操作")
}

// Search 搜索包
func (opm *OfflinePackageManager) Search(ctx context.Context, pattern string) ([]PackageInfo, error) {
	return opm.manager.Search(ctx, pattern)
}

// Info 获取包信息
func (opm *OfflinePackageManager) Info(ctx context.Context, packageName string) (*PackageInfo, error) {
	return opm.manager.Info(ctx, packageName)
}

// ListInstalled 列出已安装的包
func (opm *OfflinePackageManager) ListInstalled(ctx context.Context) ([]PackageInfo, error) {
	return opm.manager.ListInstalled(ctx)
}

// IsInstalled 检查指定包是否已安装
func (opm *OfflinePackageManager) IsInstalled(ctx context.Context, packageName string) (bool, error) {
	return opm.manager.IsInstalled(ctx, packageName)
}

// GetPackageManager 获取特定的包管理器
func GetPackageManager(managerName string, config *ManagerConfig) (PackageManager, error) {
	factory := NewManagerFactory()

	if config == nil {
		config = NewManagerConfig()
	}

	// 首先检查管理器名称是否支持
	if !isSupportedManager(managerName) {
		return nil, fmt.Errorf("不支持的包管理器: %s", managerName)
	}

	// 使用配置的PreferredName来创建特定管理器
	config.PreferredName = managerName
	
	// 根据管理器名称设置正确的ManagerType
	if isOnlineManager(managerName) {
		config.ManagerType = OnlineManagerType
	} else if isOfflineManager(managerName) {
		config.ManagerType = OfflineManagerType
	}
	
	return factory.CreateManager(config)
}

// isSupportedManager 检查管理器名称是否被支持
func isSupportedManager(managerName string) bool {
	supportedManagers := []string{"apt", "yum", "dnf", "apk", "zypper", "pacman", "dpkg", "rpm"}
	for _, name := range supportedManagers {
		if strings.EqualFold(managerName, name) {
			return true
		}
	}
	return false
}

// isOnlineManager 检查管理器名称是否为在线管理器
func isOnlineManager(managerName string) bool {
	onlineManagers := []string{"apt", "yum", "dnf", "apk", "zypper", "pacman"}
	for _, name := range onlineManagers {
		if strings.EqualFold(managerName, name) {
			return true
		}
	}
	return false
}

// isOfflineManager 检查管理器名称是否为离线管理器
func isOfflineManager(managerName string) bool {
	offlineManagers := []string{"dpkg", "rpm"}
	for _, name := range offlineManagers {
		if strings.EqualFold(managerName, name) {
			return true
		}
	}
	return false
}

// ListAvailableManagers 列出系统中可用的包管理器
func ListAvailableManagers() []string {
	factory := NewManagerFactory()
	return factory.ListAvailableManagers()
}

// DetectLinuxDistribution 检测Linux发行版
func DetectLinuxDistribution() string {
	factory := NewManagerFactory()
	return factory.DetectLinuxDistribution()
}

// GetRecommendedManager 根据发行版推荐包管理器
func GetRecommendedManager() string {
	factory := NewManagerFactory()
	return factory.GetRecommendedManager()
}
